package com.motong.gongdan.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.motong.gongdan.vo.H5Vo.Dashboard.query.*;
import com.motong.gongdan.vo.H5Vo.Dashboard.vo.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DashboardService {

    @Resource
    private WorkOrderService workOrderService;

    @Resource
    private WorkReportService workReportService;

    @Resource
    private ProcessesService processesService;

    @Resource
    private ReportBadProductService reportBadProductService;

    /**
     * 获取工单统计数据
     *
     * @param param 请求参数
     */
    public WorkOrderStatisticsVo workOrderStatistics(GetAllQuery param) {
        WorkOrderStatisticsVo workOrderStatisticsVo = workOrderService.getBaseMapper().workOrderStatistics(param);
        if (Objects.nonNull(workOrderStatisticsVo) && Objects.nonNull(workOrderStatisticsVo.getBadProductRate())) {
            workOrderStatisticsVo.setBadProductRate(workOrderStatisticsVo.getBadProductRate().multiply(BigDecimal.valueOf(100)));
        }
        return workOrderStatisticsVo;
    }

    /**
     * 获取完成量统计数据
     *
     * @param param 请求参数
     */
    public Page<FinishNumStatisticsVo> finishNumStatistic(OrderNumDetailQuery param) {
        return workOrderService.getBaseMapper().finishNumStatistic(new Page<>(param.getCurrentPage(), param.getPageSize()), param);
    }

    /**
     * 工序统计数据
     *
     * @param param 请求参数
     */
    public Page<ProcessStatisticsVo> processStatistic(ProcessDetailQuery param) {
        Page<ProcessStatisticsVo> processStatisticsVoPage = processesService.getBaseMapper().processStatistic(new Page<>(param.getCurrentPage(), param.getPageSize()), param);
        if (!CollectionUtils.isEmpty(processStatisticsVoPage.getRecords())) {
            Set<Integer> processIds = processStatisticsVoPage.getRecords().stream().map(ProcessStatisticsVo::getProcessId).collect(Collectors.toSet());
            param.setProcessIds(processIds);
            List<ProcessStatisticsMissionVo> processStatisticsMissionVos = processesService.getBaseMapper().getMissionNumByProcessId(param);
            Map<Integer, ProcessStatisticsMissionVo> processIdMissionPlanNumMap = new HashMap<>(processStatisticsMissionVos.size());
            processStatisticsMissionVos.forEach(i-> processIdMissionPlanNumMap.put(i.getProcessId(),i));
            processStatisticsVoPage.getRecords().forEach(i->{
                ProcessStatisticsMissionVo missionVo = processIdMissionPlanNumMap.get(i.getProcessId());
                i.setMissionNum(missionVo.getMissionNum()).setPlanNum(missionVo.getPlanNum());
            });
        }

        return processStatisticsVoPage;
    }

    /**
     * 报工排行统计数据
     *
     * @param param 请求参数
     */
    public Page<WorkReportStatisticsVo> workReportStatistics(WorkerRankDetailQuery param) {
        Page<WorkReportStatisticsVo> data = workReportService.getBaseMapper().workReportStatistics(new Page<>(param.getCurrentPage(), param.getPageSize()), param);
        if (!CollectionUtils.isEmpty(data.getRecords())) {
            data.getRecords().forEach(i -> i.setBadRate(i.getReportNum().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : i.getBadNum().divide(i.getReportNum(), 4, RoundingMode.HALF_UP)));
        }
        return data;
    }

    /**
     * 不良品占比统计数据
     *
     * @param param 请求参数
     */
    public List<BadProductRateStatisticsVo> badProductStatistics(GetAllQuery param) {
        List<BadProductRateStatisticsVo> badProductRateStatisticsVos = workReportService.getBaseMapper().badProductStatistics(new Page<>(param.getCurrentPage(), param.getPageSize()), param);
        if (Objects.nonNull(badProductRateStatisticsVos) && !badProductRateStatisticsVos.isEmpty()) {
            BigDecimal sum = badProductRateStatisticsVos.stream().map(BadProductRateStatisticsVo::getBadNum).reduce(BigDecimal::add).get();
            if (sum.compareTo(BigDecimal.ZERO) != 0) {
                badProductRateStatisticsVos.forEach(i -> i.setRate(i.getBadNum().divide(sum, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100))));
            }
        }
        return badProductRateStatisticsVos;
    }

    /**
     * 获取播报信息
     *
     * @param param 请求参数
     */
    public Page<BroadcastVo> broadcast(GetAllQuery param) {
        return this.workReportService.getBaseMapper().broadcast(new Page<>(param.getCurrentPage(), param.getPageSize()), param);
    }

    /**
     * 获取看板工单详情
     *
     * @param param 请求参数
     */
    public Page<H5OrderListVo> h5OrderList(H5OrderListQuery param) {
        Page<H5OrderListVo> data = workOrderService.getBaseMapper().h5OrderList(new Page<>(param.getCurrentPage(), param.getPageSize()), param);
        if (Objects.nonNull(data.getRecords()) && !data.getRecords().isEmpty()) {
            Set<String> orderCodes = data.getRecords().stream().map(H5OrderListVo::getWorkOrderCode).collect(Collectors.toSet());
            // 获取工序列表
            List<ProcessStatisticsVo> processData = getProcessesByOrderCodes(orderCodes);
            Map<String, List<ProcessStatisticsVo>> codeProcessMap = processData.stream().collect(Collectors.groupingBy(ProcessStatisticsVo::getWorkOrderCode));
            data.getRecords().forEach(i -> i.setProcessStatisticsVos(codeProcessMap.get(i.getWorkOrderCode())));
        }
        return data;
    }

    /**
     * 根据工单编码获取任务并排序
     *
     * @param orderCodes 工单编码
     */
    public List<ProcessStatisticsVo> getProcessesByOrderCodes(Set<String> orderCodes) {
        return processesService.getBaseMapper().getByOrderCodes(orderCodes).stream().sorted((f, s) -> ((f.getLast() == 0 || s.getLast() == 0) && !f.getLast().equals(s.getLast())) ? (f.getLast() == 0 ? 1 : -1) : (f.getLast() - s.getLast())).collect(Collectors.toList());
    }


    /**
     * 获取看板工单分类数量
     *
     * @param param 请求参数
     */
    public List<Map<String, Object>> h5OrderListCountByStatus(H5OrderListQuery param) {
        return workOrderService.getBaseMapper().h5OrderListCountByStatus(param);
    }

    /**
     * 不良品分布详情
     *
     * @param param 请求参数
     */
    public Page<BadProductRateStatisticsVo> badProductDistributed(BadProductDistributedQuery param) {
        Page<BadProductRateStatisticsVo> data = workReportService.getBaseMapper().badProductDistributed(new Page<>(param.getCurrentPage(), param.getPageSize()), param);
        BigDecimal sum = data.getRecords().stream().map(BadProductRateStatisticsVo::getBadNum).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        data.getRecords().forEach(i -> {
            i.setReportBadRate(Objects.nonNull(i.getReportBadRate()) ? i.getReportBadRate().multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO);
            if (sum.compareTo(BigDecimal.ZERO) != 0) {
                i.setRate(i.getBadNum().divide(sum, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
            }
        });
        return data;
    }
}
